﻿using Abp;
using Abp.Application.Services;
using FwProject.Manager;
using FwProject.ShopApplication;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Abp.ObjectMapping;
using FwProject.ShoppingMall.EventAdvertising;
using Abp.Domain.Repositories;
using X.PagedList;
using System.Linq;
using AutoMapper.QueryableExtensions;
using Abp.UI;
using FwProject.ShoppingMall.Com;
using FwProject.ShoppingMall.Shop;
using Abp.Runtime.Caching;
using Abp.AutoMapper;
using Microsoft.EntityFrameworkCore;

namespace FwProject.EventAdvertising.Dto
{
    /// <summary>
    /// 秒杀管理
    /// </summary>

    public class ShopSecondkillAppService : FwProjectAppServiceBase, IShopSecondkillAppService
    {
        private readonly ShopSecondkillManager _shopSecondkillManager;
        private readonly IRepository<ShopSecondkill, Guid> _shopSecondkillRepository;

        private readonly IRepository<ShopOrder, Guid> _shopOrderRepository;
        private readonly IRepository<ShopOrderDetails, Guid> _shopOrderDetailsRepository;
        private readonly IRepository<ShopProduct, Guid> _shopProductRepository;
        private Abp.IGuidGenerator _guid { get; set; }
        public IObjectMapper _map { get; set; }
        private readonly ICacheManager _catchmanager;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="shopSecondkillManager"></param>
        /// <param name="shopSecondkillRepository"></param>
        /// <param name="shopOrderDetailsRepository"></param>
        /// <param name="shopOrderRepository"></param>
        public ShopSecondkillAppService(ShopSecondkillManager shopSecondkillManager, IRepository<ShopSecondkill, Guid> shopSecondkillRepository,
            IRepository<ShopOrderDetails, Guid> shopOrderDetailsRepository,
            IRepository<ShopOrder, Guid> shopOrderRepository,
            IRepository<ShopProduct, Guid> shopProductRepository,
             ICacheManager catchmanager)
        {

            _shopProductRepository = shopProductRepository;
            _shopOrderRepository = shopOrderRepository;
            _shopOrderDetailsRepository = shopOrderDetailsRepository;
            _shopSecondkillManager = shopSecondkillManager;
            _guid = SequentialGuidGenerator.Instance;
            _map = NullObjectMapper.Instance;
            _catchmanager = catchmanager;
            _shopSecondkillRepository = shopSecondkillRepository;
        }
        /// <summary>
        /// 创建一个秒杀活动
        /// </summary>
        /// <param name="Input"></param>
        /// <returns></returns>
        public async Task<Guid> CreateShopSecondkill(ShopSecondkillInput Input)
        {
            var model = _map.Map<ShopSecondkill>(Input);
            model.Id = _guid.Create();
            var list = _shopSecondkillRepository.GetAll().Where(o => o.ShopProductId == Input.ShopProductId && o.SecondkillEndTime >= Input.SecondkillEndTime).FirstOrDefault();
            if (list != null)
                throw new UserFriendlyException("已存在一个相同的秒杀商品");

            return await _shopSecondkillManager.CreateShopSecondkill(model);
        }
        /// <summary>
        /// 修改一个秒杀
        /// </summary>
        /// <param name="Input"></param>
        /// <returns></returns>
        public async Task EditShopSecondkill(Guid Id, ShopSecondkillInput Input)
        {
            var model = _shopSecondkillRepository.Get(Id);
            model = _map.Map(Input, model);
            await _shopSecondkillManager.UpdateShopSecondkill(model);
        }
        /// <summary>
        /// 删除一个秒杀
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public async Task DeleteShopSecondkill(Guid Id)
        {
            var model = _shopSecondkillRepository.Get(Id);
            await _shopSecondkillManager.DeleteShopUserCoupon(model);
        }
        /// <summary>
        /// 通过商品id查看商品是否秒杀商品
        /// </summary>
        /// <param name="shopId"></param>
        /// <returns></returns>
        public async Task<ShopSecondkillDto> GetAppByShopIdSkill(Guid shopId)
        {

            var list = (await GetCatchshopSecondkillDtos).Where(o=>o.ShopProductId==shopId);
            var model = _shopSecondkillRepository.GetAll().Where(o => o.ShopProductId == shopId).FirstOrDefault();
            if (model != null)
              {
                if (model.SecondkillEndTime <= DateTime.Now) {
                    await _shopSecondkillRepository.DeleteAsync(model);
                    var m= _shopProductRepository.Get(shopId);
                    m.ShopProductFlag = ShopProductFlag.正常;
                }
                return model.MapTo<ShopSecondkillDto>();
              }
            return null;
        }






        /// <summary>
        /// app获取秒杀商品信息分页查询查看所有的秒杀信息
        /// </summary>
        /// <param name="page"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public async Task<IPagedList<ShopSecondkillAppDto>> GetAppSecondkillPageList(int page, int pageSize)
        {

            var list = _shopSecondkillRepository.GetAll().Where(o => o.SecondkillEndTime >= DateTime.Now);
            var listModel = await list.OrderByDescending(o => o.CreationTime).Join(_shopProductRepository.GetAll().Where(o=>o.ShopProductFlag==ShopProductFlag.秒杀),o=>o.ShopProductId,t=>t.Id,(o,t)=>new ShopSecondkillAppDto
            {
                Id = o.Id,
                ShopProductId = o.ShopProductId,
                SecondkillPrice = o.SecondkillPrice,
                SecondkillCount = o.SecondkillCount,
                SecondkillSingleCount = o.SecondkillSingleCount,
                SecondkillBeginTime = o.SecondkillBeginTime,
                SecondkillEndTime = o.SecondkillEndTime,
                SecondkillTitle = o.SecondkillTitle,
                CreatorUserId = o.CreatorUserId,
                CreationTime = o.CreationTime,
                ShopProductInfo =new ShopProductSkillDto {
                    ShopTypeid=t.ShopTypeid,
                    ImagePic=t.ImagePic,
                    ProductName=t.ProductName,
                    ProductNumber=t.ProductNumber,
                    MarketPrice=t.MarketPrice,
                    ProductDetails=t.ProductDetails,
                    Unit=t.Unit,
                    SpceWeight=t.SpceWeight
                },
                SecondkillPayCount = _shopOrderDetailsRepository.GetAll().Where(b => b.ShopproductId == o.ShopProductId).Join(
                  _shopOrderRepository.GetAll().Where(b => b.PayStatus == PayStatus.已支付), n => n.OrderId, k => k.Id, (b, c) => new
                  {
                      m = b.ProductCount

                  }).Sum(n => n.m)

            }).ToPagedListAsync(page, pageSize);

            return listModel;
        }


        #region 后台管理

        public async Task<LayerDataBaseDto> GetSpikeLayerDataAsync(int page, int limit, string keyword, string range)
        {
            var query = _shopSecondkillRepository.GetAll().OrderByDescending(o=>o.CreationTime).Join(_shopProductRepository.GetAll(), i => i.ShopProductId, j => j.Id, (i, j) => new ShopSecondkillOutputDto
            {
                Id = i.Id,
                SecondkillTitle = i.SecondkillTitle,
                ShopProductName = j.ProductName,
                SecondkillPrice = i.SecondkillPrice,
                SecondkillCount = i.SecondkillCount,
                SecondkillBeginTime = i.SecondkillBeginTime,
                SecondkillEndTime = i.SecondkillEndTime
            });

            if (!string.IsNullOrEmpty(keyword))
                query = query.Where(o => o.SecondkillTitle.Contains(keyword) || o.ShopProductName.Contains(keyword));

            switch (range)
            {
                case "Going"://进行中
                    query = query.Where(o => o.SecondkillBeginTime < DateTime.Now && o.SecondkillEndTime > DateTime.Now);
                    break;
                case "Not"://未开始
                    query = query.Where(o => o.SecondkillBeginTime > DateTime.Now);
                    break;
                case "Over"://已结束
                    query = query.Where(o => o.SecondkillEndTime < DateTime.Now);
                    break;
                default:
                    break;
            }

            var pagelist = await query.ToPagedListAsync(page, limit);

            LayerDataBaseDto dto = new LayerDataBaseDto();
            dto.Data = pagelist;
            dto.Count = pagelist.TotalItemCount;
            return dto;
        }

        public async Task<ShopSecondkillOutputDto> GetEntityByIdAsync(Guid id)
        {
            var query = _shopSecondkillRepository.GetAll().Where(o => o.Id == id).Join(_shopProductRepository.GetAll(), i => i.ShopProductId, j => j.Id, (i, j) => new ShopSecondkillOutputDto
            {
                Id = i.Id,
                SecondkillTitle = i.SecondkillTitle,
                ShopProductId = j.Id,
                ShopProductName = j.ProductName,
                SecondkillSingleCount = i.SecondkillSingleCount,
                SecondkillPrice = i.SecondkillPrice,
                SecondkillCount = i.SecondkillCount,
                SecondkillBeginTime = i.SecondkillBeginTime,
                SecondkillEndTime = i.SecondkillEndTime
            });

            var entity = await query.FirstAsync();
            return entity;
        }

        public async Task ModifyAsync(Guid id, ShopSecondkillBackstageEnterDto input)
        {
            var entity = await _shopSecondkillRepository.GetAsync(id);
            input.MapTo(entity);
            if (!string.IsNullOrEmpty(input.SecondkillDateRange))
            {
                var timerange = input.SecondkillDateRange.Split('~');
                if (timerange.Count() == 2)
                {
                    entity.SecondkillBeginTime = Convert.ToDateTime(timerange[0].Trim());
                    entity.SecondkillEndTime = Convert.ToDateTime(timerange[1].Trim());

                    if (entity.SecondkillEndTime>DateTime.Now)//判断是否还在活动时间
                    {
                        var shop = await _shopProductRepository.GetAsync(entity.ShopProductId);
                        shop.ShopProductFlag = ShopProductFlag.秒杀;
                        await _shopProductRepository.UpdateAsync(shop);
                    }
                }
            }

            await _shopSecondkillManager.UpdateShopSecondkill(entity);

        }

        public async Task CreateBatchesAsync(ShopSecondkillBackstageEnterDto input)
        {
            DateTime beginTime = new DateTime();
            DateTime endTime = new DateTime();
            if (!string.IsNullOrEmpty(input.SecondkillDateRange))
            {
                var timerange = input.SecondkillDateRange.Split('~');
                if (timerange.Count() == 2)
                {
                    beginTime = Convert.ToDateTime(timerange[0].Trim());
                    endTime = Convert.ToDateTime(timerange[1].Trim());
                }
            }
            switch (input.EventGoodsRange)
            {
                case EventGoodsRange.All://全部商品
                    var shopproducts = await _shopProductRepository.GetAll().Where(o => o.IsGrounding).ToListAsync();
                    foreach (var item in shopproducts)
                    {
                        item.ShopProductFlag = ShopProductFlag.秒杀;
                        await _shopProductRepository.UpdateAsync(item);

                        ShopSecondkill entity = input.MapTo<ShopSecondkill>();
                        entity.Id = _guid.Create();
                        entity.ShopProductId = item.Id;
                        entity.SecondkillBeginTime = beginTime;
                        entity.SecondkillEndTime = endTime;
                        await _shopSecondkillManager.CreateShopSecondkill(entity);
                    }
                    break;
                case EventGoodsRange.Part://部分商品
                    foreach (var item in input.ShopProductIds)
                    {
                        var shop = await _shopProductRepository.GetAsync(item);
                        shop.ShopProductFlag = ShopProductFlag.秒杀;
                        await _shopProductRepository.UpdateAsync(shop);

                        ShopSecondkill entity = input.MapTo<ShopSecondkill>();
                        entity.Id = _guid.Create();
                        entity.ShopProductId = item;
                        entity.SecondkillBeginTime = beginTime;
                        entity.SecondkillEndTime = endTime;
                        await _shopSecondkillManager.CreateShopSecondkill(entity);
                    }
                    break;
                default:
                    break;
            }

        }

        #endregion

        /// <summary>
        /// 秒杀的购物车
        /// </summary>
        public Task<List<ShopSecondkillDto>> GetCatchshopSecondkillDtos
        {
            get
            {

                ICache cache = _catchmanager.GetCache(nameof(ShopSecondkill));
                return cache.GetAsync($"list", async () => await _shopSecondkillRepository.GetAll().Where(o => o.SecondkillEndTime >= DateTime.Now).ProjectTo<ShopSecondkillDto>().ToListAsync());

            }

        }
    }
}
